
import React, { useEffect, useRef, useState } from 'react';
import Taro, { FC, useDidShow, useRouter } from '@tarojs/taro';
import { View, Text, Image, Button, Input, Label, Video } from '@tarojs/components';
import { combineLatest, EMPTY, of, Subject, Subscription } from 'rxjs';
import { debounceTime, filter, mergeMap, switchMap, tap } from 'rxjs/operators';
import classNames from 'classnames';

import { getLogger } from '@/utils/log';
import { useMsgFacade } from '@/hooks/useMsgFacade';
import { useAuthFacade } from '@/hooks/useAuthFacade';
import { LIVE_TYPE, ROOM_ROLE } from '@/constants/room';
import Login from '@/components/loginPopup';
import { formatTime, isObject, isObjEmpty } from '@/utils';
import storage from '@/utils/storage';
import { GetStorage } from '@/models/response/roomRsp';
import { useRoomUiFacade } from '@/hooks/useRoomUiFacade';

import "taro-ui/dist/style/components/grid.scss";
import "taro-ui/dist/style/components/button.scss"; // 按需引入 
import './index.scss';
import { useRoomFacade } from './useRoomFacade';

//直播详情页
export const LiveDetails: FC = () => {
  const logger = getLogger("/pages/liveRoom/LiveDetails");

  //直播间缩略图规格
  const picUrlPostfix = "?imageView2/1/w/500/h/280";

  const router = useRouter();
  const sceneRef = useRef(""); //扫小程序码的scene值
  //分享卡片进来的路径必带下面两个参数，扫码进入的只带上面的scene参数
  const roomIdRef = useRef(router.params.roomId || "");
  const refIdref = useRef(router.params.refId || "");

  const [, , , , , , , , , , , , , , , , , , , , , , , , , allowShare] = useRoomUiFacade();
  const [authFacade, loginStatus] = useAuthFacade();
  const [
    roomFacade,
    roomName,
    anchorName,
    ownerName,
    ownerId,
    roomRole,
    orgName,
    orgLogo,
    description,
    startTime,
    endTime,
    passwd,
    picUrl,
    forceSign,
    preLoadVideo,
    type,
    anchorId
  ] = useRoomFacade();

  //消息门面文件
  const [msgFacade] = useMsgFacade();
  const [isFocus, setIsFocus] = useState(false)
  const [isclose, setIsclose] = useState(false)
  const [num, setNum] = useState('');
  const initSubject = () => new Subject<string>();
  // 初始化按钮接收参数subject
  const [emitter, setEmitter] = useState(initSubject);
  //登录弹窗组件相关状态
  const [clicked, setClicked] = useState(false);
  //测试onshow
  // const [isOnshow, setIsOnshow] = useState(false)
  // const [option, setOption]: any = useState()
  const toRoom = () => {
    // 未登录但有密码或签到设置， 需要跳出登录弹窗
    if (!loginStatus && roomRole === ROOM_ROLE.AUDIENCE && (forceSign || !!passwd)) {
      //这个时候需要登录弹窗
      setClicked(true);
      return;
    }


    // 每次点击都读取缓存
    const Data = storage.get('signIned') || []
    let data = {} as GetStorage
    Data.map(i => { if (i.roomId === roomIdRef.current) return data = i });
    // console.log('data是否为签到状态', data);

    // 放行列表和需要处理的情况. 如果不是观众，可以跳过密码和签到
    if (roomRole !== ROOM_ROLE.AUDIENCE || (!passwd && !forceSign) || (passwd && !!data.pwded && !forceSign) || (forceSign && !!data.signIned || !passwd)) {
      // if ((!passwd && !forceSign) || (passwd && data.pwded && !forceSign) || (forceSign && data.signIned || !passwd)) {
      if (type == 0) {
        if (roomRole === ROOM_ROLE.AUDIENCE && forceSign && (!data || !data.signIned)) {
          Taro.navigateTo({
            url: `/subPages/liveRoom/signIn/index?roomId=${roomIdRef.current}&liveType= ${LIVE_TYPE.TEXT}`
          })
        } else {
          Taro.navigateTo({
            url: `/pages/liveRoom/graphicLive/index?roomId=${roomIdRef.current}`
          })
        }
      } else {
        Taro.navigateTo({
          url: `/pages/liveRoom/room/index?roomId=${roomIdRef.current}`
          // url: `/subPages/liveRoom/room/index?roomId=${roomIdRef.current}`
        })
      }
    } else {
      //如果需要密码并且没有输入过密码
      if (passwd && (!data || !data.pwded)) {
        setIsclose(true)
        setIsFocus(true)
      } else if (forceSign && (!data || !data.signIned)) { //需要签到的情况
        jumpForceSign();
      }
    }
  }

  // 判断是否要签到
  const jumpForceSign = () => {
    Taro.navigateTo({
      // url: `/pages/liveRoom/signIn/index?roomId=${roomIdRef.current}`
      url: `/subPages/liveRoom/signIn/index?roomId=${roomIdRef.current}&liveType= ${LIVE_TYPE.VIDEO}`
    })
  }

  //关闭密码输入框
  const handleClose = () => {
    setIsclose(false)
    setIsFocus(false)//收起键盘
  }
  //点击方块区域聚焦唤起键盘
  const enterNumber = () => {
    setIsFocus(true)
  }

  //onblur事件键盘收起
  const cancelKey = () => {
    setIsFocus(false)
  }

  useEffect(() => {
    const sub = combineLatest([emitter.asObservable(), roomFacade.passwd$, roomFacade.forceSignIn$])
      .pipe(
        tap(([input]) => {
          //渲染密码
          setNum(input);
        }),
        filter(([input]) => {
          const i = input as string;
          return i.length >= 4;
        }),
        tap(([input, pass, forceSignIn]) => {
          const i = input as string;

          if (i.trim() == pass.trim()) {
            setIsclose(false)
            setIsFocus(false)//收起键盘

            // let data = storage.get(roomIdRef.current);
            const Data: GetStorage[] = storage.get('signIned') || [];
            Data.map((data, index) => {
              if (data.roomId === roomIdRef.current) {
                if (!!data && isObject(data)) {
                  data = Object.assign(data, { pwded: true })
                } else {
                  data = { roomId: roomIdRef.current, pwded: true }
                }
                // DataItem = data
                Data.splice(index, 1, data)
              }
              if (forceSignIn && (!data || !data.signIned)) {
                jumpForceSign();
              }
            })

            //写密码输入状态的缓存,缓存一星期
            storage.put('signIned', Data, 7 * 24 * 3600);
          } else {
            Taro.showToast({
              title: ' 密码错误',
              icon: 'none',
              duration: 2000
            })
          }
        })
      )
      .subscribe(
        {
          next: () => {
            console.log('完成状态检查');
          },
          error: () => setEmitter(initSubject)
        }
      )

    return () => sub.unsubscribe()
  }, [emitter, roomIdRef.current])

  //FIXME: 只有开启了强制签到才需要获取用户是否已签到的数据
  useEffect(() => {
    const subscriptions: Subscription[] = [
      //参数里任何一个流发出值都会组合发送到下一个操作符，注意和zip以及forkJion的区别
      authFacade.loginStatus$
        .pipe(
          debounceTime(500),
          filter(() => !!roomIdRef.current),
          switchMap(isLogin => {
            if (isLogin) {
              return of(true);
            } else {
              //未登录也可以加群
              msgFacade.applyJoinBigGroup(roomIdRef.current)
              return EMPTY;
            }
          })
        )
        .subscribe(),
    ]

    return () => { subscriptions.map(sub => sub.unsubscribe()) };
  }, [roomIdRef.current])

  useEffect(() => {
    const subscriptions: Subscription[] = [
      authFacade.loginStatus$
        .pipe(
          mergeMap(isLogin => {
            //通过扫小程序码或者分享卡片进入
            if (sceneRef.current || refIdref.current) {
              if (!isLogin) {
                return EMPTY;
              } else {
                //获取scene自带的refId，或者分享卡片自带的refId
                const refId = sceneRef.current ? sceneRef.current : refIdref.current;
                return roomFacade.getRoomByRef(refId)
                  .pipe(
                    tap(roomId => {
                      roomIdRef.current = roomId
                      console.log('通过分享id获取到的roomId:', roomId)
                    })
                  )
              }
            } else {
              return of(roomIdRef.current);
            }
          }
          ),
          tap(roomId => {
            //重置房间state数据
            roomFacade.resetRoomStore(roomId);
            //重置房间聊天数据
            msgFacade.resetMsgStore(roomId);
          }),
          switchMap(roomFacade.enterRoom),
          //非主播身份，如果有强制签到则获取签到状态
          mergeMap(roomData => {
            //如果没有强制签到则直接判断角色并返回
            if (isObjEmpty(roomData) || !roomData.forceSignIn) {
              roomFacade.judgeRole();
              return EMPTY;
            } else {
              return of(roomData);
            }
          }),
          switchMap(() => roomFacade.getUserSignInfo(roomIdRef.current)),
          tap(res => {
            // 用户已签到 signIned 为true 
            let needSignIn = false // 设置中间状态减少代码量
            if (res.signInContent && res.signInContent.length > 0) {
              needSignIn = true
            }
            let data: GetStorage[] = storage.get('signIned') || [];
            if (!!data && data.length > 0) {
              let flag = true
              data.map((i, index) => {
                if (i.roomId === roomIdRef.current) {
                  flag = false
                  data.splice(index, 1, Object.assign(i, { signIned: needSignIn }))
                }
              })
              if (flag) {
                data.push({ roomId: roomIdRef.current, signIned: needSignIn })
              }
            } else {
              data = [{ roomId: roomIdRef.current, signIned: needSignIn }]
            }
            storage.put('signIned', data, 7 * 24 * 3600);
            //写签到状态的缓存,缓存一星期
            // } else {
            //   // 用户未签到
            //   let data = storage.get('signIned') || [];
            //   if (!!data && data.length > 0) {
            //     let flag = true;
            //     data.map((i, index) => {
            //       if (i.roomId === roomIdRef.current) {
            //         data.splice(index, 1, { roomId: roomIdRef.current, signIned: false })
            //         flag = false;
            //         return
            //       }
            //     })
            //     if (flag) {
            //       data.push({ roomId: roomIdRef.current, signIned: false })
            //     }
            //   } else {
            //     data.push({ roomId: roomIdRef.current, signIned: false })
            //   }
            //   storage.put('signIned', data, 7 * 24 * 3600);
            // }
          }),
          tap(roomFacade.judgeRole)
        )
        .subscribe()
    ]

    return () => { subscriptions.map(sub => sub.unsubscribe()) };
  }, [])

  // 对应 onShow
  useDidShow(async () => {
    roomFacade.clearUiOperate(); //清理操作，以免直播间页面返回本页面后，重进直播间所重复触发的副作用
    // msgFacade.clearNotifyMsg();

    // 获取小程序启用时返回的参数
    const options = Taro.getLaunchOptionsSync();

    // FIXME 判断是否通过小程序码进入，如果后续需要从另外的表里面获取roomId，则需要考虑异步的情况
    if (options.query && options.query.scene && (options.scene === 1047 || options.scene === 1048 || options.scene === 1049)) {
      sceneRef.current = options.query.scene;
      setClicked(true);  //这个情况下要求必须先弹窗登录
    }

    //从单人或群消息里的小程序卡片进入
    if (options.query && (options.scene === 1007 || options.scene === 1008)) {
      // refIdref.current = options.query.refId;
      setClicked(true);  //这个情况下要求必须先弹窗登录
    }
  })

  // 转发分享
  // useShareAppMessage(res => {
  //   return {
  //     title: `${roomName}`,
  //     imageUrl: picUrl + '?imageMogr2/thumbnail/660x540/pad/1',
  //     path: `/pages/index/index?roomId=${roomIdRef.current}&refId=${refIdref.current}`,
  //   }
  // })


  //顶部图片或者视频
  const Top = ({ preVideo }) => {
    if (!preVideo) {
      return <Image src={picUrl == '' ? ASSETS_PATH + "/live_Blackground.png" + picUrlPostfix : picUrl + picUrlPostfix} className='top_img'></Image>
    } else {
      return <Video id='video' src={preVideo} playBtnPosition='center' autoplay className='top_img'></Video>
    }
  }

  const TopMemo = React.memo(Top)

  return (
    <View className='index'>
      <View className='top'>
        <TopMemo preVideo={preLoadVideo}></TopMemo>
      </View>
      <View className='main'>
        <View className='title'>
          <Text>{roomName}</Text>
        </View>
        <View className='content'>
          <View className='ct-left'>
            <View className='name'><Text>主持人</Text></View>
            <View className='addName'><Text>机构名称</Text></View>
            <View className='time'><Text>直播时间</Text></View>
          </View>
          <View className='ct-right'>
            <View className='name'><Text>{anchorId ? anchorName : ownerName}</Text></View>
            <View className='addName'><Text>{orgName || '暂无'}</Text></View>
            <View className='time'><Text>{formatTime(startTime) + ' - ' + formatTime(endTime)}</Text></View>
          </View>
        </View>
        {/* {isOnshow && <View><Text>测试此时有触发onShow, {option}</Text></View>}
        {!isOnshow && <View><Text>此时没有触发onShow</Text></View>} */}
        <View className='tip' >
          <Text>简介</Text>
        </View>
        <View className='tip_ct'>
          <Text>{description || '暂无'}</Text>
        </View>
      </View>
      <Button className='button' onClick={toRoom}>
        <View className='bt-box'>
          <View className='text2'>进入直播</View>
          <Image src='https://leconglive-wxapp-1301839528.file.myqcloud.com/wxIcon/play.png' className='playImg'></Image>
        </View>
      </Button>
      {passwd && isclose && roomRole === ROOM_ROLE.AUDIENCE && (
        <View className='tipsBox' style={{ display: isclose == true ? 'block' : 'none' }} >
          <View className='model'>
            <View className='close' onClick={handleClose} >
              <Image src='https://leconglive-wxapp-1301839528.file.myqcloud.com/wxIcon/close.png' className='close_img'></Image>
            </View>
            <View className='tips'>请输入密码，不知道可以咨询主办方哟!</View>
            <View className='label-content' onClick={enterNumber}>
              <Label className={classNames("code", { active: num.length === 0 })}>{num[0]}</Label>
              <Label className={classNames("code", { active: num.length === 1 })}>{num[1]}</Label>
              <Label className={classNames("code", { active: num.length === 2 })}>{num[2]}</Label>
              <Label className={classNames("code", { active: num.length === 3 || num.length === 4 })}>{num[3]}</Label>
            </View>
            <Input
              className='two-code'
              autoFocus
              type='number'
              maxlength={4}
              focus={isFocus}
              onInput={(ev) => { emitter.next(ev.detail.value as string) }}
              onBlur={cancelKey}
            />
          </View>
        </View>
      )}

      <Login clicked={clicked} setClicked={setClicked} />
    </View>
  )
}

export default LiveDetails